/**
 * @Author: 陈瑞鹏
 * @Date:   2022-10-15 10:32:01
 * @Last Modified by:   陈瑞鹏
 * @Last Modified time: 2023-10-31 19:09:18
 */

import crypto from 'crypto';
import { Response } from 'express';
import fs from 'fs';
export default class utils {

  constructor() { }

  /**
   * md5加密
   * @param str 加密字符串
   * @returns
   */
  static md5(str: string) {
    let hash = crypto.createHash('md5'); // hash
    let sign = hash.update(str).digest('hex');
    return sign;
  }

  /**
   * 获取ip
   * @param req
   * @returns
   */
  static getClientIp(req: any): string {
    let result: string = req.headers['x-real-ip-forward'] ||
      req.headers['x-real-ip'] ||
      req.headers['x-forwarded-for'] ||
      req['connection'].remoteAddress ||
      req['socket'].remoteAddress ||
      (req['connection'] && req['connection']['socket'].remoteAddress);
    return result;
  }


  /**
   * 获取json文件全部内容
   * @param filename 文件名
   */
  static get_all_json(filename: string) {
    return new Promise(async (resolve, reject) => {
      fs.readFile('./public/json/' + filename, 'utf8', async (err, json) => {
        if (err) reject(`${filename}, ${err.toString()}`);
        let data = JSON.parse(json);
        resolve(data);
      })
    })
  }

  /**
   * 获取json文件内容id匹配的数据
   * @param filename 文件名
   * @param id 需要对应的ID
   * @param idKey 文件内对应的idKEy
   * @returns
   */
  static get_id_json(filename: string, id: number, idKey: string) {
    return new Promise((resolve, reject) => {
      fs.readFile('./public/json/' + filename, 'utf8', (err, json) => {
        if (err) reject(`${filename}, ${err.toString()}`);
        let data = JSON.parse(json);
        for (const iterator of data) {
          if (iterator[idKey] == id) {
            resolve(iterator);
          }
        }
        resolve(null)
      })
    })
  }

  /**
   * 获取json文件内容id匹配的多条部分数据
   * @param filename 文件名
   * @param id 需要对应的ID
   * @param idKey 文件内对应的idKEy
   * @returns
   */
  static get_part_json(filename: string, id: number, idKey: string) {
    return new Promise((resolve, reject) => {
      fs.readFile('./public/json/' + filename, 'utf8', (err, json) => {
        if (err) reject(err);
        let data = JSON.parse(json);
        let part = [];
        for (const iterator of data) {
          if (iterator[idKey] == id) {
            part.push(iterator);
          }
        }
        resolve(part)
      })
    })
  }


  /**
   * 流转base64
   * @param query 需要转化的参数
   * @returns
   */
  static buffer_base64(query: string | object) {
    if (typeof query == 'object') return Buffer.from(JSON.stringify(query))

    return Buffer.from(query).toString('base64')
  }


  /**
   * 距离日期
   * @param date1 小日期
   * @param date2 大日期
   */
  static dateMinus(date1: string, date2: string) {//date1:小日期   date2:大日期
    var sdate = new Date(date1);
    var now = new Date(date2);
    var days = now.getTime() - sdate.getTime();
    var day = parseInt((days / (1000 * 60 * 60 * 24)).toString());
    return day;
  }


  /**
   * 根据概率返回数据
   * @param arr 概率数组
   * @param key 字段key  概率比例
   * @returns
   */
  static async chance(arr: any, key: string, roleId?: number): Promise<any> {
    // 修改概率
    let roleIdArr = ['1'];
    if (roleId) {
      let code = roleIdArr.indexOf(roleId.toString())
      if (code != -1) {
        for (const iterator of arr) {
          switch (iterator.type) {
            case 'hero':
              iterator.chance = 0.5;
              break;
          }
        }
      }
    }
    let gArr = [];
    for (let i = 0; i < arr.length; i++) {
      gArr.push(arr[i][key])
    }
    let data = arr[this.getResult(gArr)]
    return data
  }

  static getResult(arr: any): any {
    var leng = 0;
    for (var i = 0; i < arr.length; i++) {
      leng += arr[i]
    }
    for (var i = 0; i < arr.length; i++) {
      var random = Math.random() * leng;
      if (random < arr[i]) {
        return i
      }
      else {
        leng -= arr[i]
      }
    }
  }


  /**
   * 判断是否在这个时间期间
   * @param beginDateStr 开始时间
   * @param endDateStr 结束时间
   */
  static isDuringDate(beginDateStr: any, endDateStr: any) {
    var curDate = new Date(),
      beginDate = new Date(beginDateStr),
      endDate = new Date(endDateStr);
    if (curDate >= beginDate && curDate <= endDate) {
      return true;
    }
    return false;
  }

  static getNextMonth(date: any) {
    var arr = date.split('-');
    var year = arr[0]; //获取当前日期的年份
    var month = arr[1]; //获取当前日期的月份
    var day = arr[2]; //获取当前日期的日
    var days: any = new Date(year, month, 0);
    days = days.getDate(); //获取当前日期中的月的天数
    var year2 = year;
    var month2: any = parseInt(month) + 1;
    if (month2 == 13) {
      year2 = parseInt(year2) + 1;
      month2 = 1;
    }
    var day2 = day;
    var days2: any = new Date(year2, month2, 0);
    days2 = days2.getDate();
    if (day2 > days2) {
      day2 = days2;
    }
    if (month2 < 10) {
      month2 = '0' + month2;
    }

    var t2 = year2 + '-' + month2 + '-' + day2;
    return t2;
  }

  static change(val: any) {
    if (typeof val != 'number') {
      console.error('不是数字');
      return
    }

    let str1 = val.toLocaleString() + '';
    let str = str1.replace(/,/g, "");
    let strLength = str.length;

    const units = ['K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y', 'S', 'O', 'N', 'H', 'X'];
    if (strLength <= 3) {
      return str;
    } else if (strLength > 42) {
      return 999 + 'max';
    } else {
      const unitIndex = Math.ceil(strLength / 3) - 2
      const unit = units[unitIndex]
      const leftLength = strLength - (3 * (Math.ceil(strLength / 3) - 1))
      return str.substring(0, leftLength) + '.' + str.substring(leftLength, leftLength + 2) + unit
    }
  }

  static timestampToTime(timestamp: any) {
    var date = new Date(timestamp);//时间戳为10位需*1000，时间戳为13位的话不需乘1000
    let Y = date.getFullYear() + '-';
    let M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
    let D = (date.getDate() < 10 ? '0' + (date.getDate()) : date.getDate()) + ' ';
    let h = (date.getHours() < 10 ? '0' + (date.getHours()) : date.getHours()) + ':';
    let m = (date.getMinutes() < 10 ? '0' + (date.getMinutes()) : date.getMinutes()) + ':';
    let s = (date.getSeconds() < 10 ? '0' + (date.getSeconds()) : date.getSeconds());
    return Y + M + D + h + m + s;
  }

  static removePropertyOfNull(obj: any) {
    Object.keys(obj).forEach(item => {
      if (!obj[item]) delete obj[item]
    })
    return obj;
  }

  /**
   * 时间差信息
   * @param direct_time 击杀时间
   * @returns
   */
  static async time_dis(startTime: any, direct_time: any) {
    // direct_time格式为yyyy-mm-dd hh:mm:ss 指定时间
    var now_time = Date.parse(new Date(startTime).toString());//当前时间的时间戳
    var end_time = Date.parse(new Date(direct_time).toString());//指定时间的时间戳
    //计算相差天数
    var time_dis = end_time - now_time;
    var days = Math.floor(time_dis / (24 * 3600 * 1000));
    //计算出小时数
    var leave1 = time_dis % (24 * 3600 * 1000);//计算天数后剩余的毫秒数
    var hours = Math.floor(leave1 / (3600 * 1000));
    //计算相差分钟数
    var leave2 = leave1 % (3600 * 1000);//计算小时数后剩余的毫秒数
    var minutes = Math.floor(leave2 / (60 * 1000));
    //计算相差秒数
    var leave3 = leave2 % (60 * 1000);//计算小时数后剩余的毫秒数
    var second = leave3 / 1000;

    return { desc: days + "天" + hours + "小时" + minutes + "分" + second + "秒", ttl: time_dis };
  }


  /**
   * 判断数组值是否相同
   * @param array 数组   [0,0,0,0]  相同返回true
   * @returns
   */
  static isAllEqual(array: any[]) {
    if (array.length > 0) {
      return !array.some((value, index) => {
        return value !== array[0];
      })
    } else {
      return true
    }
  }

  /**
   * 根据某个日期来根据天数获取天数之后的日期
   * @param startDate 某个日期
   * @param days 天数
   * @returns
   */
  static getTargetDate(startDate, days) {
    var startTime = new Date(startDate).getTime();
    var diff = days * 86400 * 1000;
    var endTime = startTime + diff;
    var d = new Date(endTime);
    var CurrentDate = "";
    CurrentDate += (d.getFullYear());
    //var year=(d.getFullYear())+"-"+(d.getMonth()+1)+"-"+(d.getDate());
    if ((d.getMonth() + 1) > 9) {
      CurrentDate += "-" + (d.getMonth() + 1);
    }
    else {
      CurrentDate += "-0" + (d.getMonth() + 1);
    }
    if ((d.getDate()) > 9) {
      CurrentDate += "-" + (d.getDate());
    }
    else {
      CurrentDate += "-0" + (d.getDate());
    }
    return CurrentDate;
  }

  /**
   * 判断当前时间是否在某一段时间段
   * 例 if (this.timeRange("08:00", "22:00")) {}
   * @param beginTime 
   * @param endTime 
   */
  static timeRange(beginTime, endTime) {
    let strb = beginTime.split(":");
    if (strb.length != 2) return false;

    let stre = endTime.split(":");
    if (stre.length != 2) return false;

    let b = new Date();
    let e = new Date();
    let n = new Date();

    b.setHours(strb[0]);
    b.setMinutes(strb[1]);
    e.setHours(stre[0]);
    e.setMinutes(stre[1]);

    if (n.getTime() - b.getTime() >= 0 && n.getTime() - e.getTime() < 0) {
      return true;
    } else {
      return false;
    }
  }

  /**
   * 获取当前第几周
   * @returns 
   */
  static getNowWeek() {
    var date1 = new Date(),
      date2 = new Date(date1.getFullYear(), 0, 1),
      d = Math.round((date1.valueOf() - date2.valueOf()) / 86400000);
    return Math.ceil((d + ((date2.getDay() + 1) - 1)) / 7); //当前是今年的第几周
  }

  static get_rand_string = function (bit) {
    var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
    var tempLen = chars.length;
    var tempStr = '';
    for (var i = 0; i < bit; ++i) {
      tempStr += chars.charAt(Math.floor(Math.random() * tempLen));
    }
    return tempStr.toLocaleUpperCase();
  };

  /**
     *  定义一个函数来将数据按照每50条为一组进行分组
     * @param data 数据
     * @param groupSize 分组大小 
     * @returns 
     */
  static groupData(data, groupSize) {
    const groups = [];
    let startIndex = 0;
    let endIndex = groupSize;

    while (startIndex < data.length) {
      groups.push(data.slice(startIndex, endIndex));
      startIndex = endIndex;
      endIndex += groupSize;
    }

    return groups;
  }

  /**
   * 打乱数组
   * @param arr 
   * @returns 
   */
  static randArr(arr) {
    for (var i = 0; i < arr.length; i++) {
      var iRand = Number(arr.length * Math.random());
      var temp = arr[i];
      arr[i] = arr[iRand];
      arr[iRand] = temp;
    }
    return arr;
  }

  static shuffle(arr) {
    return arr.sort(() => Math.random() - 0.5);
  }
}